package com.zbs.framework.dao.role.service.impl;

import com.zbs.framework.common.utils.Constant;
import com.zbs.framework.common.utils.ErrEnum;
import com.zbs.framework.common.utils.ErrorAssert;
import com.zbs.framework.common.utils.PageData;
import com.zbs.framework.dao.role.entity.Role;
import com.zbs.framework.dao.role.model.RoleListItem;
import com.zbs.framework.dao.role.repository.RoleRepository;
import com.zbs.framework.dao.role.service.RoleService;
import com.zbs.framework.dao.rolefunction.repository.RoleFunctionRepository;
import com.zbs.framework.dao.rolefunction.service.RoleFunctionService;
import com.zbs.framework.dao.user.repository.UserRoleRepository;
import com.zbs.framework.dao.utils.jpa.JpaQueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Zbs
 * 2019-04-28 11:38
 */
@Service
@Transactional
public class RoleServiceImpl implements RoleService {

    @Autowired
    private RoleRepository roleRepository;
    @Autowired
    private RoleFunctionService roleFunctionService;
    @Autowired
    private RoleFunctionRepository roleFunctionRepository;
    @Autowired
    private UserRoleRepository userRoleRepository;
    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Role add(String name, Integer enabled, String description,String type) {
        // 参数检查
        ErrorAssert.hasLength(name, "Name can not be empty!");
        ErrorAssert.notNull(enabled, "Enabled can not be null!");
        type = StringUtils.hasLength(type) ? type : "1";
        // 名称查重
        assertNameAva(name,type);
        // persist
        Role role = new Role(name, enabled, Constant.YES, description,type);
        roleRepository.save(role);
        return role;
    }

    @Override
    public void deleteRoleExistsUser(Integer roleId) {
        boolean existsByRoleId = this.userRoleRepository.existsByRoleId(roleId);
        ErrorAssert.isTrue(!existsByRoleId,"该角色下有用户正在使用，不可删除");
        this.delete(roleId);
    }

    @Override
    public Role add(String name, Integer enabled, String description,String type, List<Long> functionIds) {
        // 参数检查
        ErrorAssert.trimHasLength(name, "Name can not be empty!");
        ErrorAssert.notNull(enabled, "Enabled can not be null!");
        Role role = this.add(name, enabled, description,type);
        this.roleFunctionService.editRoleFunctions(role.getId(),functionIds);
        return role;
    }

    @Override
    public void edit(Integer id, String name, Integer enabled, String description,String type) {
        // 参数检查
        ErrorAssert.notNull(id, "Id can not be null!");
        ErrorAssert.hasLength(name, "Name can not be empty!");
        // 查找角色
        Role role = roleRepository.findById(id).orElse(null);
        ErrorAssert.notNull(role, "Role not found");
        // 检查角色是否可编辑
        ErrorAssert.isTrue(Constant.YES.equals(role.getEditable()), ErrEnum.THIS_ROLE_IS_NOT_EDITABLE);
        // 角色名称查重
        if (!role.getName().equals(name)) assertNameAva(name,type);
        // 修改信息
        role.setName(name);
        if (enabled != null){
            role.setEnabled(enabled);
        }
        if (StringUtils.hasLength(type)) {
            role.setType(type);
        }
        role.setDescription(description);
        roleRepository.save(role);
    }

    private void assertNameAva(String name, String type){
        List<Role> exists = roleRepository.findByNameAndType(name,type);
        ErrorAssert.isTrue(CollectionUtils.isEmpty(exists), ErrEnum.ROLE_NAME_DUPLICATED);
    }

    @Override
    public void delete(Integer id) {
        // 参数检查
        ErrorAssert.notNull(id, "Id can not be null!");
        // 查找
        Role role = roleRepository.findById(id).orElse(null);
        ErrorAssert.notNull(role, "Role not found");
        // 检查角色是否可编辑
        ErrorAssert.isTrue(Constant.YES.equals(role.getEditable()), ErrEnum.THIS_ROLE_IS_NOT_EDITABLE);
        //删除用户角色关系
        this.userRoleRepository.deleteAllByRoleId(id);
        // 删除角色功能关系
        this.roleFunctionRepository.deleteByRoleId(id);
        // 删除
        roleRepository.delete(role);
    }

    @Override
    public List<RoleListItem> findList(String quickSeek, Integer enabled,String type) {
        List<Role> roleList = new JpaQueryWrapper<>(Role.class,entityManager)
                .orLike(Role::getName,quickSeek)
                .orLike(Role::getDescription,quickSeek)
                .eq(Role::getType,type)
                .list();
        // 封装数据
        List<RoleListItem> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(roleList)){
            roleList.forEach(role -> result.add(new RoleListItem(role)));
        }
        return result;
    }

    @Override
    public PageData<RoleListItem> findList(Integer pageIndex, Integer pageSize, String quickSeek, Integer enabled, String type) {
        Page<Role> page = new JpaQueryWrapper<>(Role.class, entityManager)
                .orLike(Role::getName, quickSeek)
                .orLike(Role::getDescription, quickSeek)
                .eq(Role::getType, type)
                .page(pageIndex, pageSize);
        // 封装数据
        List<RoleListItem> result = new ArrayList<>();
        if (!CollectionUtils.isEmpty(page.getContent())){
            page.getContent().forEach(role -> result.add(new RoleListItem(role)));
        }
        return new PageData<>(result,page.getTotalElements());
    }
}
